package com.cloudream.glsimple;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.SurfaceTexture;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;
import android.opengl.Matrix;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

import com.cloudream.glsimple.utils.ShaderUtils;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.Arrays;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

/**
 * Created by Administrator on 2018/10/19 0019.
 */

public class SimpleTextureActivity extends AppCompatActivity {


    public static final String vertexShaderStr =
            "attribute vec4 vPosition;" +
                    "attribute vec2 vCoordinate;" +
                    "uniform mat4 vMatrix;" +

                    "varying vec2 aCoordinate;" +
                    "void main(){" +
                    "gl_Position = vMatrix * vPosition;" +
                    "aCoordinate = vCoordinate;" +
                    "}";


    public static final String fragmentShaderStr =
            "precision mediump float;" +
                    "uniform sampler2D vTexture;" +//取样器
                    "varying vec2 aCoordinate;" +
                    "" +
                    "void main(){" +
                    "gl_FragColor = texture2D(vTexture,aCoordinate);" +//GLSL 2d 纹理取样
                    "}";



    private float[] mViewMatrix = new float[16];
    private float[] mProjectMatrix = new float[16];
    private float[] mMVPMatrix = new float[16];

    private FloatBuffer bPos;
    private FloatBuffer bCoord;

    //三角形顶点坐标
    private final float[] sPos = {
            -1.0f, 1.0f,    //左上角
            -1.0f, -1.0f,   // 左下角
            1.0f, 1.0f,     //右上角
            1.0f, -1.0f     // 右下角
    };

    // 纹理坐标
    private final float[] sCood = {
            0.0f, 0.0f,
            0.0f, 1.0f,
            1.0f, 0.0f,
            1.0f, 1.0f
    };

    GLSurfaceView glSurfaceView = null;

    private int glHPosition;
    private int glHTexture;
    private int glHCoordinate;
    private int glHMatrix;
    // gles program handle
    private int mProgram;

    private float uXY;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


        glSurfaceView = new GLSurfaceView(this);
        setContentView(glSurfaceView);
        Bitmap bitmap = null;
        try {
            bitmap =  BitmapFactory.decodeStream(getAssets().open("fengj.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        glSurfaceView.setEGLContextClientVersion(2);
        glSurfaceView.setRenderer(new TextureRender(bitmap));
        glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
    }


    private class TextureRender implements GLSurfaceView.Renderer {


        Bitmap bitmap ;

        public TextureRender(Bitmap bitmap){
            this.bitmap = bitmap;
        }

        @Override
        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
            GLES20.glClearColor(1.0f,1.0f,1.0f,1.0f);
            GLES20.glEnable(GLES20.GL_TEXTURE_2D);


            ByteBuffer bb = ByteBuffer.allocateDirect(sPos.length *4);
            bb.order(ByteOrder.nativeOrder());
            bPos = bb.asFloatBuffer();
            bPos.put(sPos);
            bPos.position(0);

            ByteBuffer cc = ByteBuffer.allocateDirect(sCood.length * 4);
            cc.order(ByteOrder.nativeOrder());
            bCoord = cc.asFloatBuffer();
            bCoord.put(sCood);
            bCoord.position(0);


            int vertextShader = ShaderUtils.loadShader(GLES20.GL_VERTEX_SHADER,vertexShaderStr);
            int fragmentShader = ShaderUtils.loadShader(GLES20.GL_FRAGMENT_SHADER,fragmentShaderStr);
            mProgram = GLES20.glCreateProgram();
            GLES20.glAttachShader(mProgram,vertextShader);
            GLES20.glAttachShader(mProgram,fragmentShader);
            GLES20.glLinkProgram(mProgram);

            glHPosition = GLES20.glGetAttribLocation(mProgram,"vPosition");
            glHCoordinate = GLES20.glGetAttribLocation(mProgram,"vCoordinate");
            glHMatrix = GLES20.glGetUniformLocation(mProgram,"vMatrix");
            glHTexture = GLES20.glGetUniformLocation(mProgram,"vTexture");

        }

        @Override
        public void onSurfaceChanged(GL10 gl, int width, int height) {
            GLES20.glViewport(0,0,width,height);

            int w = bitmap.getWidth();
            int h = bitmap.getHeight();

            /**
             * 图像比
             */
            float picRatiowh = w/(float)h;
            /**
             * 屏幕占比
             */
            float sWidthHeight = width/(float)height;
            uXY = sWidthHeight;
            if(width > height){ // 模屏
                if(picRatiowh > sWidthHeight){// 图像的比较长
                    Matrix.orthoM(mProjectMatrix,0,-sWidthHeight *picRatiowh,sWidthHeight*picRatiowh,-1,1,3,5);
                }else{
                    Matrix.orthoM(mProjectMatrix,0,-sWidthHeight/picRatiowh,sWidthHeight/picRatiowh,-1,1,3,5);
                }
            }else{
                if(picRatiowh > sWidthHeight){
                    Matrix.orthoM(mProjectMatrix,0,-1,1,-1/sWidthHeight * picRatiowh,1/sWidthHeight*picRatiowh,3,5);
                }else{
                    Matrix.orthoM(mProjectMatrix, 0, -1, 1, -picRatiowh/sWidthHeight, picRatiowh/sWidthHeight,3, 5);
                }
            }

            Log.d("Terry", Arrays.toString(mProjectMatrix));
            Matrix.setLookAtM(mViewMatrix,0,0,0,5.0f,0f,0f,0f,0f,1.0f,0.0f);
            Matrix.multiplyMM(mMVPMatrix,0,mProjectMatrix,0,mViewMatrix,0);
        }

        @Override
        public void onDrawFrame(GL10 gl) {
            GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT| GLES20.GL_DEPTH_BUFFER_BIT);
            GLES20.glUseProgram(mProgram);
            GLES20.glUniformMatrix4fv(glHMatrix,1,false,mMVPMatrix,0);
            GLES20.glEnableVertexAttribArray(glHPosition);
            GLES20.glEnableVertexAttribArray(glHCoordinate);
            GLES20.glUniform1i(glHTexture,0);
            createTexture();
            GLES20.glVertexAttribPointer(glHPosition,2,GLES20.GL_FLOAT,false,0,bPos);
            GLES20.glVertexAttribPointer(glHCoordinate,2,GLES20.GL_FLOAT,false,0,bCoord);
            GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP,0,4);


            GLES20.glDisableVertexAttribArray(glHPosition);
            GLES20.glDisableVertexAttribArray(glHCoordinate);
        }


        private int createTexture(){
            int[] texture = new int[1];
            if(bitmap != null && !bitmap.isRecycled()){
                //
                GLES20.glGenBuffers(1,texture,0);
                GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,texture[0]);
                GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MIN_FILTER,GLES20.GL_NEAREST);
                GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MAG_FILTER,GLES20.GL_LINEAR);
                //设置环绕方向S，截取纹理坐标到[1/2n,1-1/2n]。将导致永远不会与border融合
                GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,GLES20.GL_CLAMP_TO_EDGE);
                //设置环绕方向T，截取纹理坐标到[1/2n,1-1/2n]。将导致永远不会与border融合
                GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,GLES20.GL_CLAMP_TO_EDGE);
                GLUtils.texImage2D(GLES20.GL_TEXTURE_2D,0,bitmap,0);


                return texture[0];
            }
            return 0;
        }
    }

}
